<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /* 
      思路：先实现基于字符串计算的基础计算器。
            遇到括号，我们肯定要优先计算括号。因此额外定义一个栈，遇到非) 就入栈。
            遇到)括号，我们就需要找到之前最近的一个左括号。即判断栈尾端是否为(即可。
            然后将字符组合起来进行计算。注意，因为是栈，所以我们要注意组合的顺序。最后让tempStr=''
      */
      function fn(s) {
        let stack = []
        let tempStr = ''

        for (let i = 0; i < s.length; i++) {
          if (s[i] == ' ') continue
          if (s[i] == ')') {
            let lastChar = stack[stack.length - 1]
            //让栈里元素循环出栈，直至找到左括号
            while (lastChar != '(') {
              tempStr = stack.pop() + tempStr
              lastChar = stack[stack.length - 1]
            }
            //弹出左括号
            stack.pop()
            stack.push(baseCalculate(tempStr))
            tempStr = ''
          } else {
            stack.push(s[i])
          }
        }
        let str = ''
        for (let i = 0; i < stack.length; i++) {
          str += stack[i]
        }
        return baseCalculate(str)
      }
      console.log(fn('(1+(4+5+2)-3)+(6+8)'))

      function baseCalculate(s) {
        s = s + '+'
        let count = 0
        //栈里永远存放可直接相加的数字 (-代表负数)
        let stack = []
        let pre = '+'
        for (let i = 0; i < s.length; i++) {
          if (s[i] == ' ') continue
          //遇到数字,可能有多位
          if (+s[i] >= 0 && +s[i] <= 9) {
            count = count * 10 + Number(s[i])
          } else {
            //当前遇到了符号需要判断之前的符号
            switch (pre) {
              case '+':
                stack.push(count)
                break
              case '-':
                stack.push(-count)
                break
              case '*':
                let num = stack.pop()
                stack.push(num * count)
                break
              case '/':
                let n = stack.pop()
                stack.push(parseInt(n / count))
                break
            }
            pre = s[i]
            count = 0
          }
        }
        return stack.reduce((pre, cur) => (pre += cur))
      }
    </script>
  </body>
</html>
